package com.idopartx.phonelightning.widget.screen

import android.animation.ValueAnimator
import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.view.View
import android.view.animation.LinearInterpolator
import com.idopartx.phonelightning.widget.KBubbleUtils

class LinePathView(context: Context?, attrs: AttributeSet?) : View(context, attrs) {
    var direction: Path.Direction = Path.Direction.CCW
        set(value) {
            field = value
        }
    private val paint: Paint = Paint(Paint.ANTI_ALIAS_FLAG)
    private val dst: Path

    private var length: Float = 0f
    private var rightAnimValue: Float = 0f
    private var leftAnimValue: Float = 0f
    private val radius = 50f
    private var screenWidth: Int = 0
    private var screenHeight: Int = 0

    var lineWidth: Int = 10
        set(value) {
            field = value + 10
            paint.strokeWidth = com.idopartx.phonelightning.widget.KBubbleUtils.dp2px(field).toFloat()
        }

    var lineLength: Float = 400f
        set(value) {
            field = 400f + 50 * value
        }


    var speed: Float = 0.002f
        set(value) {
            field = 0.002f + (value / 2000)
        }


    lateinit var pathMeasure: PathMeasure

    private var animator: ValueAnimator? = null

    var type = 0
        set(value) {
            field = value
            rightAnimValue = (screenWidth + lineLength - (radius / 2)) / length
            leftAnimValue = (screenWidth * 2 + screenHeight + lineLength - (radius / 2)) / length
        }

    init {
        paint.style = Paint.Style.STROKE
        paint.color = Color.parseColor("#ff5000")
        paint.strokeWidth = com.idopartx.phonelightning.widget.KBubbleUtils.dp2px(lineWidth).toFloat()

        dst = Path()


        // 画一个圆, 关联pathMeasure
        // 创建属性动画
        animator = ValueAnimator.ofFloat(0f, 1f)
        animator?.duration = 5000
        animator?.interpolator = LinearInterpolator()
        animator?.repeatCount = ValueAnimator.INFINITE
        animator?.addUpdateListener { invalidate() }
        animator?.start()
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        screenHeight = h
        screenWidth = w

        val path = Path()
        path.moveTo(radius, 0f)
        path.lineTo(screenWidth - radius, 0f)
        path.cubicTo(
            screenWidth - radius / 2,
            0f,
            screenWidth.toFloat(),
            radius / 2,
            screenWidth.toFloat(),
            radius
        )
        path.lineTo(screenWidth.toFloat(), screenHeight - radius)
        //
        path.cubicTo(
            screenWidth.toFloat(),
            screenHeight - radius / 2,
            screenWidth - radius / 2,
            screenHeight.toFloat(),
            screenWidth - radius,
            screenHeight.toFloat()
        )
        path.lineTo(radius, screenHeight.toFloat())
        path.cubicTo(
            radius / 2,
            screenHeight.toFloat(),
            0f,
            screenHeight - radius / 2,
            0f,
            screenHeight - radius
        )
        path.lineTo(0f, radius)
        path.cubicTo(0f, radius / 2, radius / 2, 0f, radius, 0f)
        pathMeasure = PathMeasure() // 测量Path的类
        pathMeasure.setPath(path, true)
        length = pathMeasure.length // 路径长度


        //渐变颜色.colors和pos的个数一定要相等


        val colors = intArrayOf(
            Color.parseColor("#4FBCB5"),
            Color.parseColor("#9D27DC"),
            Color.parseColor("#4FBCB5")
        )
        val pos = floatArrayOf(0f, 0.5f, 1f)
        val linearGradient =
            LinearGradient(0f, 0f, lineLength, lineLength, colors, pos, Shader.TileMode.REPEAT)
        val matrix = Matrix()
        linearGradient.setLocalMatrix(matrix)
        paint.shader = linearGradient

        rightAnimValue = (w + lineLength - (radius / 2)) / length
        leftAnimValue = (w * 2 + h + lineLength - (radius / 2)) / length

    }


    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        rightAnimValue = drawLine(dst, rightAnimValue, canvas)
        if (type == 1) {
            leftAnimValue = drawLine(dst, leftAnimValue, canvas)
        }
    }

    private fun drawLine(dst: Path, animValue: Float, canvas: Canvas): Float {
        var tempAnimValue = animValue
        dst.reset()

        if (direction == Path.Direction.CW) {
            tempAnimValue += speed
        } else {
            tempAnimValue -= speed

        }
        dst.lineTo(0f, 0f) // 解决硬件加速的bug
        val stop = length * tempAnimValue
        val start = stop - lineLength
        if (tempAnimValue >= 1) {
            pathMeasure.getSegment(
                length * tempAnimValue - lineLength,
                length,
                dst,
                true
            ) // 截取整个path的任何片段(开始长度 / 结束长度 / 保存截取的路径 / 是否从起点开始截取)
            canvas.drawPath(dst, paint)
            pathMeasure.getSegment(
                0f,
                length * (tempAnimValue - 1),
                dst,
                true
            ) // 截取整个path的任何片段(开始长度 / 结束长度 / 保存截取的路径 / 是否从起点开始截取)
            canvas.drawPath(dst, paint)
            if (tempAnimValue > 1 + lineLength / length) {
                tempAnimValue = lineLength / length
            }
        } else if (tempAnimValue <= lineLength / length) {
            pathMeasure.getSegment(
                0f,
                length * tempAnimValue,
                dst,
                true
            )
            canvas.drawPath(dst, paint)

            pathMeasure.getSegment(
                (1 + tempAnimValue) * length - lineLength,
                length,
                dst,
                true
            )
            canvas.drawPath(dst, paint)

            if (tempAnimValue < 0) {
                tempAnimValue = 1f
            }
        } else {
            pathMeasure.getSegment(
                start,
                stop,
                dst,
                true
            ) // 截取整个path的任何片段(开始长度 / 结束长度 / 保存截取的路径 / 是否从起点开始截取)
            canvas.drawPath(dst, paint)
        }
        return tempAnimValue
    }
}